#!/usr/bin/python
#coding=utf-8

import sys
import os
import rados
import threading
import rbd
import re
import commands
import copy
import json
import logging
import logging.config

import global_list
from command import *

class ReqImage:
    #self.h=链接集群的handle
    def __init__(self,handle,dict,reqid,logger):
        self.h=handle
        self.act=dict['act']
        self.page=dict['page']
        self.pagesize=dict['pagesize']
        self.val=dict['val']
        self.item=dict['item']
        self.pool=dict['pool']
        self.reqid=int(reqid)
        self.logger=logger

    def ThreadDealer(self):
        resp={}
        resp['act']=str(self.act)
        resp['type']='image'
        resp['status']='running'
        if self.act == 'getallstats' or self.act == 'getstats' or \
           self.act == 'getstatsbyregex' or self.act == 'getblklist':
            resp['page']=self.page
        if self.act == 'getstats' or self.act == 'getstatsbyregex':
            resp['pool']=str(self.pool)
        if self.act == 'delblklist':
            resp['item']=self.item

        #tname=threading.currentThread().getName()
        mtx=global_list.get_value('MUTEX')
        #加锁->获取结果列表->追加结果->更新列表->解锁
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        res[int(self.reqid)]=copy.deepcopy(resp)
        global_list.set_value('RESULTS',res)
        mtx.release()

        #执行具体命令
        if self.act == 'getpoolname':
            ret=self.getpoolname()
            if False == ret.has_key('err'):
                resp.update(ret)
                resp['status']='success'
            else:
                resp['status']='failed'
        elif self.act == 'getallstats':
            ret=self.getallstats()
            if False == ret.has_key('err'):
                resp.update(ret)
                resp['status']='success'
            else:
                resp['status']='failed'
        elif self.act == 'getstats':
            ret=self.getstats()
            if False == ret.has_key('err'):
                resp.update(ret)
                resp['status']='success'
            else:
                resp['status']='failed'
        elif self.act == 'getstatsbyregex':
            ret=self.getstatsbyregex()
            if False == ret.has_key('err'):
                resp.update(ret)
                resp['status']='success'
            else:
                resp['status']='failed'
        elif self.act == 'getblklist':
            ret=self.getblklist()
            if False == ret.has_key('err'):
                resp.update(ret)
                resp['status']='success'
            else:
                resp['status']='failed'
        elif self.act == 'delblklist':
            ret=self.delblklist()
            if True == ret:
                resp['status']='success'
            else:
                resp['status']='failed'
        else:
            pass
 
        #更新结果
        mtx=global_list.get_value('MUTEX')
        mtx.acquire()
        res=global_list.get_value('RESULTS')
        res[int(self.reqid)]=copy.deepcopy(resp)
        global_list.set_value('RESULTS',res)
        mtx.release()

    #获取集群pool列表
    def getpoolname(self):
        respdict=dict()
        resplist=[]
      
        #获取pool的名称和ID
        pool_stats = CephClusterCommand(self.h, prefix='osd lspools', format='json')
        if pool_stats.has_key('err') == True:
            self.logger.error("reqid:"+str(self.reqid)+" osd lspools failed, error is "+pool_stats['err'])
            respdict['err']=pool_stats['err']
            return respdict
        pools=pool_stats['result']

        for pool in pools:
            d=dict()
            d['id']=pool['poolnum']
            d['name']=pool['poolname']
            resplist.append(d)
        respdict['pool']=resplist

        self.logger.info("reqid:"+str(self.reqid)+" success")
        return respdict

    #查询集群所有pool中的所有image
    def getallstats(self):
        respdict=dict()
        respdict['pagesize']=self.pagesize
        templist=[]
        num=0  

        #获取pool列表
        pools=self.h.list_pools()
        for i in pools:
            #打开一个pool
            ioctx=self.h.open_ioctx(i)
            rbd_inst = rbd.RBD()
            imglist=rbd_inst.list(ioctx)
            num+=len(imglist)
            for j in imglist:
                tempdict=dict()
                tempdict['image']=j
                tempdict['pool']=i
                templist.append(tempdict)
            ioctx.close()
        respdict['count']=num
        self.logger.info("reqid:"+str(self.reqid)+" there are "+str(num)+" images in all pools")

        #获取整个page范围内的数据
        start_idx=int(self.pagesize)*(int(self.page)-1)
        end_idx=start_idx+int(self.pagesize)
        respdict['images']=templist[start_idx:end_idx]

        #获取client和session
        for i in respdict['images']:
            cmd="/usr/bin/rbd status "+str(i['pool'])+'\/'+str(i['image'])+" --format json"
            ret,val=commands.getstatusoutput(cmd)
            if ret != 0:
                self.logger.error("reqid:"+str(self.reqid)+" rbd status failed, ret is "+str(ret))
                respdict['err']='rbd status failed'
                return respdict

            buf=json.loads(val)
            if 0 == len(buf['watchers']):
                i['client']='None'
                i['session']='None'
                i['watchers']=[]
            else:
                watchlist=[]
                for j in buf['watchers']:
                    d=dict()
                    d['client']=j.get('address','None')
                    d['session']=j.get('client','None')
                    watchlist.append(d)
                i['watchers']=watchlist

        self.logger.info("reqid:"+str(self.reqid)+" success")
        return respdict

    #根据给定poolname查询所有的image信息
    def getstats(self):
        respdict=dict()
        resplist=[]

        #打开一个pool，并关联到该pool中的所有image
        ioctx=self.h.open_ioctx(str(self.pool))
        rbd_inst = rbd.RBD()
        imglist=rbd_inst.list(ioctx)
 
        #选取范围
        start_idx=int(self.pagesize)*(int(self.page)-1)
        end_idx=start_idx+int(self.pagesize)
        respdict['pool']=self.pool
        respdict['pagesize']=self.pagesize
        respdict['count']=len(imglist)
        templists=imglist[start_idx:end_idx]
        ioctx.close()
        self.logger.info("reqid:"+str(self.reqid)+" there are "+str(respdict['count'])+" images in "+str(self.pool)+" pool")
 
        #获取整个page范围内的数据
        for i in templists:
            cmd="/usr/bin/rbd status "+str(self.pool)+'\/'+str(i)+" --format json"
            ret,val=commands.getstatusoutput(cmd)
            if ret != 0:
                self.logger.error("reqid:"+str(self.reqid)+" rbd status failed, ret is "+str(ret))
                respdict['err']='rbd status failed'
                return respdict

            buf=json.loads(val)
            d=dict()
            d['image']=i
            if 0 == len(buf['watchers']):
                d['client']='None'
                d['session']='None'
                d['watchers']=[]
            else:
                watchlist=[]
                for j in buf['watchers']:
                    t=dict()
                    t['client']=j.get('address','None')
                    t['session']=j.get('client','None')
                    watchlist.append(t)
                d['watchers']=watchlist
            resplist.append(d)
        
        respdict['images']=resplist
        self.logger.info("reqid:"+str(self.reqid)+" success")
        return respdict

    #在给定的poolname中模糊查询符合条件的image
    def getstatsbyregex(self):
        respdict=dict()
        resplist=[]

        #打开一个pool，并关联到该pool中的所有image
        ioctx=self.h.open_ioctx(str(self.pool))
        rbd_inst = rbd.RBD()
        imglist=rbd_inst.list(ioctx)
        templist=[ x for x in imglist if None != re.search(str(self.val),x)]

        start_idx=int(self.pagesize)*(int(self.page)-1)
        end_idx=start_idx+int(self.pagesize)
        respdict['pool']=self.pool
        respdict['page']=self.page
        respdict['pagesize']=self.pagesize
        respdict['count']=len(templist)
        resultlist=templist[start_idx:end_idx]
        ioctx.close()
        self.logger.info("reqid:"+str(self.reqid)+" there are "+str(respdict['count'])+" images in "+str(self.pool)+" pool matched")
 
        for i in resultlist:
            cmd="/usr/bin/rbd status "+str(self.pool)+'\/'+str(i)+" --format json"
            ret,val=commands.getstatusoutput(cmd)
            if ret != 0:
                self.logger.error("reqid:"+str(self.reqid)+" rbd status failed, ret is "+str(ret))
                respdict['err']='rbd status failed'
                return respdict

            buf=json.loads(val)
            d=dict()
            d['image']=i
            if 0 == len(buf['watchers']):
                d['client']='None'
                d['session']='None'
                d['watchers']=[]
            else:
                watchlist=[]
                for j in buf['watchers']:
                    t=dict()
                    t['client']=j.get('address','None')
                    t['session']=j.get('client','None')
                    watchlist.append(t)
                d['watchers']=watchlist
            resplist.append(d)
    
        respdict['images']=resplist
        self.logger.info("reqid:"+str(self.reqid)+" success")
        return respdict

    #查询集群黑名单客户单列表
    def getblklist(self):
        respdict=dict()
        resplist=[]

        blklists = CephClusterCommand(self.h, prefix='osd blacklist ls', format='json')
        if blklists.has_key('err') == True:
            self.logger.error("reqid:"+str(self.reqid)+" osd blacklist ls failed, error is "+blklists['err'])
            respdict['err']=blklists['err']
            return respdict
        items=blklists['result']
        respdict['count']=len(items)

        #返回一个列表
        start_idx=int(self.pagesize)*(int(self.page)-1)
        end_idx=start_idx+int(self.pagesize)
        templists=items[start_idx:end_idx]
        idx=1
        for i in templists:
            d=dict()
            d['id']=idx
            d['name']=i.get('addr', 'None')
            resplist.append(d)
            idx+=1

        respdict['lists']=resplist
        self.logger.info("reqid:"+str(self.reqid)+" success")
        return respdict

    #删除黑名单客户端
    def delblklist(self):
        cmd='/usr/bin/ceph osd blacklist rm '+str(self.item)
        ret=os.system(cmd)
        if ret == 0:
            self.logger.info("reqid:"+str(self.reqid)+" success")
            return True
        else:
            self.logger.error("reqid:"+str(self.reqid)+" os blacklist rm "+str(self.item)+" failed,ret is "+str(ret))
            return False

    #析构
    def __del__(self):
        pass
